


/**
 *
 * @param   viewer          cesium 或 mars3d实例
 * @param   children        影像数据列表（详情参考下方children元素）
 * @param   label           用于渲染tree控件时的标签显示
 * @param   id              用于渲染tree控件
 * 
 * @function init           重置影像数据，传入新的影像列表，会根据新列表与旧列表的差异更新图层
 * @function show           指定图层显示/隐藏
 * @function upOrDown       上移下移
 * 
 */

/**
 *  children元素
 *  @param   id             唯一标识
 *  @param   url            影像地址
 *  @param   show           影像是否显示
 *  @param   alpha          透明度
 *  @param   sort           排序（会按照sort顺序，从小到大存储数据，索引较小的图层层级更高）
 *  @param   label          用于渲染tree控件时的标签显示
 */

export function BQGIS_ImageryLayerManager ({children, label = "影像", id = getUUId(), viewer}) {
    this.viewer = viewer
    this.id = id
    this.label = label
    this.children = []
    this.init(children)
}

BQGIS_ImageryLayerManager.prototype.init = function (children) {
    const keys = this.children.map(item => item.id)
    children.sort((a, b) => a.sort - b.sort)
    children.forEach(item => {
        const layerData = this.children.find(data => data.id === item.id)
        if(layerData){
            const index = keys.findIndex(id => id === item.id)
            keys.splice(index, 1)
            this.upDate(layerData, item)
            if(layerData.entity){
                this.viewer.imageryLayers.lowerToBottom(layerData.entity)
            }
        }else{
            const option = {...item}
            if(!item.id){
                item.id = getUUId()
            }
            this.setProperty(option, item)
            this.children.push(option)
            if(option.entity){
                this.viewer.imageryLayers.lowerToBottom(option.entity)
            }
        }
    })
    this.children.sort((a, b) => a.sort - b.sort)
    keys.forEach(id => {
        this.remove(id)
    })
}

BQGIS_ImageryLayerManager.prototype.setProperty = function (layerData, option) {
    this.setShow(layerData, option.show)
    this.setAlpha(layerData, option.alpha)
}

BQGIS_ImageryLayerManager.prototype.upDate = function (layerData, option) {
    if(option.url !== layerData.url){
        if(layerData.entity){
            this.viewer.imageryLayers.remove(layerData.entity)
        }
        layerData.entity = null
        layerData.url = option.url
    }
    this.setProperty(layerData, option)
    layerData = Object.assign(layerData, option)
}

BQGIS_ImageryLayerManager.prototype.setAlpha = function (layerData, alpha) {
    if(alpha == null) return
    layerData.entity.alpha = alpha
    layerData.alpha = alpha
}
 

/**
 *  上移/下移
 *  @param   id             唯一标识
 *  @param   upOrDown       up/down
 */
BQGIS_ImageryLayerManager.prototype.upOrDown = function (id, upOrDown) {
    const index = this.children.findIndex(item => item.id === id)
    if(index === -1) return
    const layerData = this.children[index]

    if(upOrDown === 'up') {
        this.viewer.imageryLayers.raise(layerData.entity)
        if(index > 0) {
            const temp = this.children[index - 1]
            this.children[index - 1] = layerData
            this.children[index] = temp
        }
    } else if(upOrDown === 'down'){
        this.viewer.imageryLayers.lower(layerData.entity)
        if(index < this.children.length) {
            const temp = this.children[index + 1]
            this.children[index + 1] = layerData
            this.children[index] = temp
        }
    }
}

/**
 *
 * 3dtiles 显示隐藏
 * 
 * @param   id              
 * @param   show            显示/隐藏
 */
BQGIS_ImageryLayerManager.prototype.show = function ({id, show}) {
    const layerData = this.get(id)
    if(layerData){
        this.setShow(layerData, show)
    }
}

BQGIS_ImageryLayerManager.prototype.get = function (id) {
    return this.children.find(item => item.id === id)
}

BQGIS_ImageryLayerManager.prototype.setShow = function (layerData, show) {
    if(!layerData.entity){
        const layer = getLayer(layerData)
        layer.readyPromise.then(res => {
            layerData.hasOpacity = layer.hasAlphaChannel  
        })
        layerData.entity = this.viewer.imageryLayers.addImageryProvider(layer)
    }
    layerData.entity.show = show
    layerData.show = show
}

BQGIS_ImageryLayerManager.prototype.remove = function (id) {
    const index = this.children.findIndex(item => item.id === id)
    const layerData = this.children[index]
    if(index !== -1){
        if(layerData.entity){
            this.viewer.imageryLayers.remove(layerData.entity)
            layerData.entity = null
        }
        this.children.splice(index, 1)
    }
}

/**
 * 获取当前所有显示的3dtiles的 id
 */
BQGIS_ImageryLayerManager.prototype.getShowKeys = function () {
    const data = []
    this.children.forEach(item => {
        if(item.show){
            data.push(item.id)
        }
    });
    return data
}

BQGIS_ImageryLayerManager.prototype.flyTo = function (id) {
    const layerData = this.get(id)
    this.viewer.flyTo(layerData.entity)
}

function getLayer(layerData) {
    if (layerData.url.indexOf("arcgis") > -1) {
        return new Cesium.ArcGisMapServerImageryProvider({
            url: layerData.url,
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
        });
    } else if (layerData.url.indexOf("tianditu") > -1) {
        return new Cesium.WebMapTileServiceImageryProvider({
            url: layerData.url,
            layer: "img",
            style: "default",
            tileMatrixSetID: "w",
            format: "tiles",
            maximumLevel: 18,
        });
    } else {
        return new Cesium.UrlTemplateImageryProvider({
            url: layerData.url,
            layer: "tdtVecBasicLayer",
            style: "default",
            format: "image/png",
            tileMatrixSetID: "GoogleMapsCompatible",
        })
    }
}


function getUUId() {
    let tem = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    let id = "",
        len = tem.length,
        i = 0
    for (i; i < len; i++) {
        if (tem[i] == "-") id += tem[i]
        else {
            let num = Math.floor(Math.random() * 16)
            id += num.toString(16)
        }
    }
    return id
}